/**
 * Created by hukekuan on 2017/12/20.
 */
function C3GIS(mapId,mapContainer) {
    var _this = this,mapOptions=null,layerList = null,olLayer,
        r = new RegExp("(^|(.*?\\/))(c3gis\.js)(\\?|$)"),
        s = document.getElementsByTagName('script'),
        src, m,baseurl;
    for(var i=0, len=s.length; i<len; i++) {
        src = s[i].getAttribute('src');
        if(src) {
            m = src.match(r);
            if(m) {
                baseurl = m[1];
                if(baseurl.split('static')[0] != ""){
                    serverName = baseurl.split('static')[0];
                }
                break;
            }
        }
    }

    if(serverName != null){
        //初始化地图
        $.ajax({
            type: 'get',
			url: serverName + 'api/ol/map/mapinit?mapid='+mapId + '&key=' + $.data(dataCache, 'key'),
            dataType: 'json',
            async: false,
            success: function(data) {
                if(data != null && data.hasOwnProperty('map')){
                    mapOptions = {
                        properties: {"mapid": mapId},
                        target: mapContainer,
                        center: data["map"]["view"]["center"] == null ?[118.360772748187, 36.13540951960175]:data["map"]["view"]["center"],
                        zoom: data["map"]["view"]["zoom"] == null ? 9:data["map"]["view"]["zoom"],
                        projection: data["map"]["view"]["projection"] == null ? "EPSG:4326":data["map"]["view"]["projection"]
                    };

                    // 添加弹窗div
                    var mapDiv = document.getElementById(mapContainer),
                        popupDiv = document.createElement("div");
                    popupDiv.setAttribute("id", "popup");
                    popupDiv.setAttribute("class", "ol-popup");
                    mapDiv.parentNode.insertBefore(popupDiv,mapDiv);

                    // 地图初始化
                    _this.mapInit(mapOptions);

                    if(data.hasOwnProperty('layer') && data["layer"].length > 0){
                        layerList = data["layer"];
                        for(var i = data["layer"].length - 1; i >= 0; i--){
                            if(data["layer"][i].hasOwnProperty('source') && data["layer"][i]['source'] != null){
                                if(data["layer"][i]['source']['type'] != 'ol.supermap.FeatureService'
                                    && data["layer"][i]['source']['type'] != 'arcgis.FeatureService'){
                                    if(data["layer"][i]['layer']['type'] == 'ol.layer.Vector'){
                                        if(data["layer"][i]['layer']['options'].hasOwnProperty('successCallBack')
                                            && data["layer"][i]['layer']['options']['successCallBack']['code'] != ''){
                                            data["layer"][i]['source']['options']['successCallBack']
                                                = eval("("+ data["layer"][i]['layer']['options']['successCallBack']['code'] +")");
                                        }
                                        if(data["layer"][i]['layer']['options']['errorCallBack'].hasOwnProperty('errorCallBack')
                                            && data["layer"][i]['layer']['options']['errorCallBack']['code'] != ''){
                                            data["layer"][i]['source']['options']['errorCallBack']
                                                = eval("("+ data["layer"][i]['options']['errorCallBack']['code'] +")");
                                        }
                                    }
                                    data["layer"][i]['layer']['source']
                                        = _this.createSourceByType(data["layer"][i]['source']['type'],data["layer"][i]['source']['options']);
                                }else {
                                    data["layer"][i]['layer']['source'] = data["layer"][i]['source'];
                                }
                                olLayer = data["layer"][i]['layer'];
                                _this.addLayer(olLayer["type"],olLayer["layerName"],olLayer);
                            }
                        }
                    }
                }
            },
            error: function (error){
                console.log(error);
            }
        });

        //获取行政区空间数据
        $.ajax({
            type: 'get',
            url: serverName + 'api/spatial/region/entry?key=' + $.data(dataCache, 'key'),
            dataType: 'json',
            success: function(data) {
                $.data(dataCache, 'region', (new ol.format.GeoJSON()).readFeatures(data));
            },
            error: function (error){
                console.log(error);
            }
        });

        //获取子行政区空间数据
        $.ajax({
            type: 'get',
            url: serverName + 'api/spatial/region/childregions?key=' + $.data(dataCache, 'key'),
            dataType: 'json',
            success: function(data) {
                $.data(dataCache, 'childregions', (new ol.format.GeoJSON()).readFeatures(data));
            },
            error: function (error){
                console.log(error);
            }
        });
    }
}

C3GIS.prototype.serverURL = function () {
    var r = new RegExp("(^|(.*?\\/))(c3gis\.js)(\\?|$)"),
        s = document.getElementsByTagName('script'),
        src, m,baseurl,serverName = null;
    for(var i=0, len=s.length; i<len; i++) {
        src = s[i].getAttribute('src');
        if(src) {
            m = src.match(r);
            if(m) {
                baseurl = m[1];
                if(baseurl.split('static')[0] != ""){
                    serverName = baseurl.split('static')[0];
                }
                break;
            }
        }
    }
    return serverName;
}

//标记矢量图层的移动和单击事件
C3GIS.prototype.interactionSelect = {pointerMove:null, click:null};
//地图点、线、面绘画事件
C3GIS.prototype.interactionDraw = null;
C3GIS.prototype.popupOverlay = null;
C3GIS.prototype.oTimer = null;
C3GIS.prototype.duration = 1000;

/**********************************map start*****************************************/
/**
 * 地图初始化
 */
C3GIS.prototype.mapInit = function (options) {
    var _this = this;
    _this.popupOverlay = new ol.Overlay({
        id:"popup",
        autoPan: true,
        autoPanAnimation: {
            duration: 250
        }
    });
    _this.mainMap = new ol.Map({
        target: options.target,
        controls: ol.control.defaults({zoom: false, attribution: false}).extend([]),
        view: new ol.View({
            center: options.center,
            zoom: options.zoom,
            minZoom: options.minZoom,
            maxZoom: options.maxZoom,
            projection: options.projection
        }),
        logo:false,
        overlays: [_this.popupOverlay]
    });

    _this.mainMap.setProperties(options["properties"]);
}

/**
 * 根据coordinate定位地图
 * @param coordinate
 * @param callBack 定位结束后的回调函数，形如function () {...}
 */
C3GIS.prototype.centerMapByCoordinate = function (coordinate,callBack) {
    if(coordinate == null) return;
    var _this = this;

    if(callBack != null){
        _this.mainMap.getView().animate({
            center:coordinate,
            duration:_this.duration
        },function (complete) {
            if (complete) {
                callBack();
            }
        });
    }else {
        _this.mainMap.getView().animate({
            center:coordinate,
            duration:_this.duration
        });
    }
}

/**
 * 根据点定位地图
 * @param point
 * @param callBack
 */
C3GIS.prototype.centerMapByPoint = function (point,callBack) {
    if(point == null) return;

    var _this = this;
    _this.centerMapByCoordinate(point.getCoordinates(),callBack);
}

/**
 * 根据Extent缩放地图（适用于多个要素的情况）
 * @param extent
 * @param callBack 缩放后的回调函数
 */
C3GIS.prototype.zoomMapByExtent = function (extent,callBack) {
    if(extent == null) return;
    var _this = this,fitParams = {
        size:this.mainMap.getSize(),
        maxZoom:12,
        duration:_this.duration
    };
    if(callBack != null){
        fitParams.callback = callBack;
    }
    _this.mainMap.getView().fit(extent,fitParams);
}

/**
 * 根据SimpleGeometry缩放地图（适用于单个要素的情况）
 * @param simpleGeometry
 * @param callBack 缩放后的回调函数
 */
C3GIS.prototype.zoomMapBySimpleGeometry = function (simpleGeometry,callBack) {
    if(simpleGeometry == null) return;
    var _this = this, geometryName = simpleGeometry.getType().toUpperCase();
    if(geometryName == 'LINESTRING'
        || geometryName == 'MULTILINESTRING'
        || geometryName == 'POLYGON'
        || geometryName == 'MULTIPOLYGON'){
        var fitParams = {
            size:this.mainMap.getSize(),
            duration:_this.duration
        };
        if(callBack != null){
            fitParams.callback = callBack;
        }
        _this.mainMap.getView().fit(simpleGeometry,fitParams);
    }else if(geometryName == 'POINT'){
        _this.centerMapByPoint(simpleGeometry,callBack)
    }
}

/**
 * 根据矢量地图要素信息缩放地图
 * @param layerName 矢量图层名称
 * @param callBack 缩放后的回调函数
 */
C3GIS.prototype.zoomMapByVectorLayer = function (layerName,callBack) {
    var _this = this;
    if(layerName == null || layerName == "") return;
    var vectorLayer = _this.getLayByName(layerName);
    if(vectorLayer != null
        && vectorLayer.getSource() != null){
        var features = vectorLayer.getSource().getFeatures();
        if(features.length > 2){
            _this.zoomMapByExtent(vectorLayer.getSource().getExtent(),callBack);
        }else if(features.length == 2){
            _this.zoomMapBySimpleGeometry(new ol.geom.Point(ol.extent.getCenter(vectorLayer.getSource().getExtent())),callBack);
        }else if(features.length == 1){
            _this.zoomMapBySimpleGeometry(features[0].getGeometry(),callBack);
        }
    }
}
/**
 * 地图状态重置
 */
C3GIS.prototype.mapReset = function () {
    var _this = this;
    _this.removeLayerByType('ol.layer.Vector');
    _this.closePopupWindow();
}

/**
 * 地图居中显示
 */
C3GIS.prototype.mapViewReset = function () {
    var _this = this;
    $.ajax({
        type: 'get',
        url: serverName + 'api/ol/map/initview?key=' + $.data(dataCache, 'key') + '&mapid=' + _this.mainMap.getProperties()['mapid'],
        dataType: 'json',
        success: function(data) {
            if(data != null && (data.hasOwnProperty('center') || data.hasOwnProperty('zoom'))){
                var viewOptions = { duration:_this.duration };
                if(data.hasOwnProperty('center') && data.center != undefined){
                    viewOptions.center = data.center;
                }
                if(data.hasOwnProperty('zoom') && data.zoom != undefined){
                    viewOptions.zoom = data.zoom;
                }
                _this.mainMap.getView().animate(viewOptions);
            }
        },
        error:function (error) {
            console.log(error);
        }
    });

}

/**
 * 地图放大
 */
C3GIS.prototype.zoomOut = function () {
    var _this = this;
    var view = _this.mainMap.getView(),
        zoom = view.getZoom();
    view.setZoom(zoom - 1);
}

/**
 * 地图缩小
 */
C3GIS.prototype.zoomIn = function () {
    var _this = this;
    var view = _this.mainMap.getView(),
        zoom = view.getZoom();
    view.setZoom(zoom + 1);
}

/**
 * 清除地图临时数据
 */
C3GIS.prototype.clearMap = function () {
    var _this = this;
    _this.removeLayerByType('ol.layer.Vector');
    _this.closePopupWindow();
    _this.removeOverlay();
}

/**
 * 地图上绘制要素
 * @param drawType 要素类型（Point：点；LineString：折线；Polygon：单面；Circle：圆；None：移除绘画事件）
 * @param callBack 绘制完要素的回调函数
 */
C3GIS.prototype.drawFeatures = function (drawType,callBack) {
    var _this = this,
        drawLayer = _this.getLayByName('drawLayer'),drawSource;
    if (drawType == undefined || drawType == null  || drawType == '') return;

    if(_this.interactionDraw != null){
        _this.mainMap.removeInteraction(_this.interactionDraw);
    }


    if(drawType != 'None'){
        if(drawLayer == null){
            _this.addLayer('ol.layer.Vector','drawLayer',null);
            drawLayer = _this.getLayByName('drawLayer');
            drawSource = new ol.source.Vector({wrapX: false});
            drawLayer.setSource(drawSource);
        }else {
            drawSource = drawLayer.getSource();
        }
        _this.interactionDraw = new ol.interaction.Draw({
            source: drawSource,
            type: drawType
        });
        _this.mainMap.addInteraction(_this.interactionDraw);

        _this.interactionDraw.on('drawend',function (evt) {
            _this.mainMap.removeInteraction(_this.interactionDraw);
            _this.interactionDraw = null;
            callBack(evt.feature);
        },this);
    }
}

/**
 * 地图导出
 */
C3GIS.prototype.exportMap = function () {
    var _this = this;
    _this.mainMap.once('postcompose', function(event) {
        var canvas = event.context.canvas;
        if (navigator.msSaveBlob) {
            navigator.msSaveBlob(canvas.msToBlob(), 'map.png');
        } else {
            canvas.toBlob(function(blob) {
                saveAs(blob, 'map.png');
            });
        }
    });
    _this.mainMap.renderSync();
}
/**********************************map end*****************************************/



/******************************interaction start************************************/
/**
 * 根据名称获取Interaction
 * @param interactionName
 * @returns {*}
 */
C3GIS.prototype.getInteractionByName = function (interactionName) {
    var _this = this, resultInteraction = null, interactionProperties,
        interactionArray = _this.mainMap.getInteractions().getArray();
    if(interactionArray.length == 0){
        return resultInteraction;
    }
    for(var i = 0,len = interactionArray.length;i < len;i++){
        interactionProperties = interactionArray[i].getProperties();
        if(interactionProperties != null
            && interactionProperties.hasOwnProperty("name")
            && interactionProperties["name"] == interactionName){
            resultInteraction = interactionArray[i];
            break;
        }
    }
    return resultInteraction;
}

/**
 * 向地图中为图层添加interaction，如果已经存在，先删除再添加
 * @param layerName
 * @param interactionType,（pointerMove、click）
 * @param interactionStyle, interaction触发样式
 * @param interactionCallback, interaction触发函数
 */
C3GIS.prototype.addInteraction = function (layerName,interactionType,interactionStyle,interactionCallback) {
    var _this = this,
        selectedLayer = _this.getLayByName(layerName);

    if(selectedLayer != null){
        if(interactionType == "pointerMove"){
            _this.interactionSelect.pointerMove = new ol.interaction.Select({
                wrapX: false,
                condition: ol.events.condition.pointerMove,
                layers: [selectedLayer],
                style: interactionStyle == null ?function(feature){
                    return null;
                } : interactionStyle
            });
            _this.mainMap.addInteraction(_this.interactionSelect.pointerMove);
        }else if(interactionType == "click"){
            _this.interactionSelect.click = new ol.interaction.Select({
                wrapX: false,
                condition: ol.events.condition.click,
                layers: [selectedLayer],
                style: interactionStyle == null ?function(feature){
                    return null;
                }: interactionStyle
            });
            _this.interactionSelect.click.on("select",interactionCallback == null ? function(e){}:interactionCallback);
            _this.mainMap.addInteraction(_this.interactionSelect.click);
        }
    }
}

/**
 * 为矢量图层添加浮动和单击事件
 * @param layerName 矢量图层名称
 * @param pointerMove 浮动事件对象，内含pointerMoveStyle（浮动样式函数）和pointerMoveCallBack（浮动回调函数）两个属性
 * @param click 点击事件对象，内含clickStyle（点击样式函数）和clickCallBack（点击事件函数）两个属性
 */
C3GIS.prototype.addInteractionForVectorLayer = function(layerName,pointerMove,click){
    var _this = this,
        pointerMoveStyle = null,
        pointerMoveCallBack = null,
        clickStyle = null,
        clickCallBack = null;
    if(layerName == null || layerName == '') return;
    _this.removeAllSelectInteraction();
    if(pointerMove != null){
        if(pointerMove.hasOwnProperty('pointerMoveStyle')){
            pointerMoveStyle = pointerMove.pointerMoveStyle;
        }
        if(pointerMove.hasOwnProperty('pointerMoveCallBack')){
            pointerMoveCallBack = pointerMove.pointerMoveCallBack;
        }
    }
    if(click != null){
        if(click.hasOwnProperty('clickStyle')){
            clickStyle = click.clickStyle
        }
        if(click.hasOwnProperty('clickCallBack')){
            clickCallBack = click.clickCallBack;
        }
    }

    if(pointerMoveStyle != null || pointerMoveCallBack != null){
        _this.addInteraction(layerName,"pointerMove",pointerMoveStyle,pointerMoveCallBack);
    }
    if(clickStyle != null || clickCallBack != null){
        _this.addInteraction(layerName,"click",clickStyle,clickCallBack);
    }
}



/**
 * 删除矢量图层的悬浮和单击事件
 */
C3GIS.prototype.removeAllSelectInteraction = function () {
    var _this = this;
    if(_this.interactionSelect.pointerMove != null){
        _this.mainMap.removeInteraction(_this.interactionSelect.pointerMove);
        _this.interactionSelect.pointerMove = null;
    }

    if(_this.interactionSelect.click != null){
        _this.mainMap.removeInteraction(_this.interactionSelect.click);
        _this.interactionSelect.click = null;
    }
}

/**
 * 删除指定名称的interaction
 * @param interactionName
 */
C3GIS.prototype.removeInteraction = function (interactionName) {
    var _this = this, selectInteraction =_this.getInteractionByName(interactionName);
    if(selectInteraction != null){
        _this.mainMap.removeInteraction(selectInteraction);
    }
}

/**
 * 为VectorLayer重新设置已经配置的Interactions
 * @param layerName 图层名称
 */
C3GIS.prototype.reSetInteractionsForVectorLayer = function (layerName) {
    if(layerName == null || layerName == '') return;
    var _this = this;
    $.ajax({
        type: 'get',
        url: serverName + 'api/ol/layer/layeroptions?key=' + $.data(dataCache, 'key') + '&layername=' + layerName,
        dataType: 'json',
        success: function(data) {
            if(data == null) return;
            var pointerMoveStyle = null, pointerMoveCallBack = null,
                clickStyle = null, clickCallBack = null;

            if(data.hasOwnProperty('stylePointerMove')
                && data.stylePointerMove != undefined
                && data.stylePointerMove.hasOwnProperty('code')
                && data.stylePointerMove.code != ''){
                pointerMoveStyle = eval('(' + data.stylePointerMove.code + ')');
            }
            if(data.hasOwnProperty('pointerMove')
                && data.pointerMove != undefined
                && data.pointerMove.hasOwnProperty('code')
                && data.pointerMove.code != ''){
                pointerMoveCallBack = eval('(' + data.pointerMove.code + ')');
            }
            if(data.hasOwnProperty('styleClick')
                && data.styleClick != undefined
                && data.styleClick.hasOwnProperty('code')
                && data.styleClick.code != ''){
                clickStyle = eval('(' + data.styleClick.code + ')');
            }
            if(data.hasOwnProperty('click')
                && data.click != undefined
                && data.click.hasOwnProperty('code')
                && data.click.code != ''){
                clickCallBack = eval('(' + data.click.code + ')');
            }

            if(pointerMoveStyle != null || pointerMoveCallBack != null){
                _this.addInteraction(layerName,"pointerMove",pointerMoveStyle,pointerMoveCallBack);
            }
            if(clickStyle != null || clickCallBack != null){
                _this.addInteraction(layerName,"click",clickStyle,clickCallBack);
            }
        },
        error: function (error){
            console.log(error);
        }
    });
}
/******************************interaction end*****************************************/





/**********************************layer start*****************************************/
/**
 * 根据图层编号获取图层
 */
C3GIS.prototype.getLayerById = function (layerId) {
    var _this = this,
        resultLayer = null,
        layerProperties,
        layerArray = _this.mainMap.getLayers().getArray();
    if(layerArray.length == 0){
        return resultLayer;
    }
    for(var i = 0,len = layerArray.length;i < len;i++){
        layerProperties = layerArray[i].getProperties();
        if(layerProperties != null
            && layerProperties.hasOwnProperty('layerId')
            && layerProperties['layerId'] == layerId){
            resultLayer = layerArray[i];
            break;
        }
    }
    return resultLayer;
}

/**
 * 根据图层名获取图层
 * @param layerName
 * @returns {*}
 */
C3GIS.prototype.getLayByName = function (layerName) {
    var _this = this,
        resultLayer = null,
        layerProperties,
        layerArray = _this.mainMap.getLayers().getArray();
    if(layerArray.length == 0){
        return resultLayer;
    }
    for(var i = 0,len = layerArray.length;i < len;i++){
        layerProperties = layerArray[i].getProperties();
        if(layerProperties != null
            && layerProperties.hasOwnProperty('name')
            && layerProperties['name'] == layerName){
            resultLayer = layerArray[i];
            break;
        }
    }
    return resultLayer;
}

/**
 * 根据配置信息生成图层并添加到地图中
 * @param layerType
 * @param layerName
 * @param layerOptions
 */
C3GIS.prototype.addLayer = function (layerType,layerName,layerOptions) {
    var _this = this,
        layer = null,
        layerProperty = {name:layerName},
        pointerMove,click;

    if(layerType == null || layerType == "") return;

    //图层初始属性添加
    if(layerOptions != null
        && layerOptions.hasOwnProperty("extent")
        && layerOptions['extent'] != null
        && layerOptions['extent'].length == 4){
        layerProperty['extent'] = layerOptions.extent
    }
    if(layerOptions != null && layerOptions.hasOwnProperty("maxResolution") && layerOptions['maxResolution'] != null){
        layerProperty['maxResolution'] = layerOptions.maxResolution
    }
    if(layerOptions != null && layerOptions.hasOwnProperty("minResolution") && layerOptions['minResolution'] != null){
        layerProperty['minResolution'] = layerOptions.minResolution
    }
    if(layerOptions != null && layerOptions.hasOwnProperty("opacity") && layerOptions['opacity'] != null){
        layerProperty['opacity'] = layerOptions.opacity
    }
    if(layerOptions != null && layerOptions.hasOwnProperty("visible") && layerOptions['visible'] != null){
        layerProperty['visible'] = layerOptions.visible
    }

    switch(layerType){
        case "ol.layer.Group":
            if(layerOptions != null
                && layerOptions.hasOwnProperty("layers")
                && Object.prototype.toString.call(layerOptions.layers) == "[object Array]"){
                layer = new ol.layer.Group({
                    layers:layerOptions.layers
                });
            }
            break;
        case "ol.layer.Tile":
            layer = new ol.layer.Tile(layerProperty);
            break;
        case "ol.layer.Vector":
            //矢量图层添加样式
            if(layerOptions != null
                && layerOptions.hasOwnProperty("options")
                && layerOptions["options"] != null
                && layerOptions["options"].hasOwnProperty("styleSet")
                && layerOptions["options"]["styleSet"] != null
                && layerOptions["options"]["styleSet"].hasOwnProperty("code")){
                layerProperty['style'] = eval('(' + layerOptions["options"]["styleSet"]["code"] + ')');
            }
            layer = new ol.layer.Vector(layerProperty);
            break;
        case "ol.layer.VectorTile":
            break;
        case "ol.layer.Heatmap":
            break;
    }
    if(layer != null){
        //给图层添加属性
        layer.setProperties({'layerType':layerType})
        if(layerOptions != null && layerOptions.hasOwnProperty("layerId") && layerOptions['layerId'] != null){
            layer.setProperties({'layerId':layerOptions['layerId']})
        }
        if(layerOptions != null && layerOptions.hasOwnProperty("aliasName") && layerOptions['aliasName'] != null){
            layer.setProperties({'aliasName':layerOptions['aliasName']})
        }

        //地图添加新增图层
        _this.mainMap.addLayer(layer);
        if(layerOptions != null && layerOptions.hasOwnProperty("source") && layerOptions['source'] != null){
            if(layerOptions['source'].hasOwnProperty('type')
                && (layerOptions['source']['type'] == 'ol.supermap.FeatureService' || layerOptions['source']['type'] == 'ol.supermap.FeatureService')){
                _this.setSource_featureService(layer,layerOptions['source']['type'],layerOptions['source']['options']);
            }else {
                layer.setSource(layerOptions.source);
            }
        }

        //矢量图层添加触发事件
        if(layerType == "ol.layer.Vector"){
            var pointerMoveStyle = null,pointerMoveCallBack = null,
                clickStyle = null,clickCallBack = null;
            _this.removeAllSelectInteraction();
            if(layerOptions != null
                && layerOptions.hasOwnProperty("options")
                && layerOptions["options"] != null
                && layerOptions["options"].hasOwnProperty("stylePointerMove")
                && layerOptions["options"]["stylePointerMove"] != null
                && layerOptions["options"]["stylePointerMove"].hasOwnProperty("code")){
                pointerMoveStyle = eval('(' + layerOptions["options"]["stylePointerMove"]["code"] + ')');
            }
            if(layerOptions != null
                && layerOptions.hasOwnProperty("options")
                && layerOptions["options"] != null
                && layerOptions["options"].hasOwnProperty("pointerMove")
                && layerOptions["options"]["pointerMove"] != null
                && layerOptions["options"]["pointerMove"].hasOwnProperty("code")){
                pointerMoveCallBack = eval('(' + layerOptions["options"]["pointerMove"]["code"] + ')');
            }
            if(layerOptions != null
                && layerOptions.hasOwnProperty("options")
                && layerOptions["options"] != null
                && layerOptions["options"].hasOwnProperty("styleClick")
                && layerOptions["options"]["styleClick"] != null
                && layerOptions["options"]["styleClick"].hasOwnProperty("code")){
                clickStyle = eval('(' + layerOptions["options"]["styleClick"]["code"] + ')');
            }
            if(layerOptions != null
                && layerOptions.hasOwnProperty("options")
                && layerOptions["options"] != null
                && layerOptions["options"].hasOwnProperty("click")
                && layerOptions["options"]["click"] != null
                && layerOptions["options"]["click"].hasOwnProperty("code")){
                clickCallBack = eval('(' + layerOptions["options"]["click"]["code"] + ')');
            }

            if(pointerMoveStyle != null || pointerMoveCallBack != null){
                _this.addInteraction(layerName,"pointerMove",pointerMoveStyle,pointerMoveCallBack);
            }
            if(clickStyle != null || clickCallBack != null){
                _this.addInteraction(layerName,"click",clickStyle,clickCallBack);
            }
        }
    }
}

/**
 * 利用geojson生成并添加矢量图层
 * @param layerName 图层名称
 * @param features feature数组
 * @param styleFunction 图层样式函数，如 function(feature) {...}
 */
C3GIS.prototype.addLayerFromFeatures  = function (layerName,features,styleFunction) {
    if(layerName == null || layerName == '' || styleFunction == null) return;
    var _this = this,vectorSource,vectorLayer;
    vectorSource = _this.createSourceByFeatures(features);
    vectorLayer = new ol.layer.Vector({
        name:layerName,
        source: vectorSource == null ? [] : vectorSource,
        style: styleFunction
    });
    vectorLayer.setProperties({'layerType':'ol.layer.Vector'});
    _this.mainMap.addLayer(vectorLayer);
}

C3GIS.prototype.addLayerFromGeoJSON  = function (layerName,geojsonObject,styleFunction) {
    if(layerName == null || layerName == '' || styleFunction == null) return;
    var _this = this,vectorSource,vectorLayer;
    vectorSource = _this.createSourceByGeojson(geojsonObject);
    vectorLayer = new ol.layer.Vector({
        name:layerName,
        source: vectorSource == null ? [] : vectorSource,
        style: styleFunction
    });
    vectorLayer.setProperties({'layerType':'ol.layer.Vector'});
    _this.mainMap.addLayer(vectorLayer);
}

/**
 * 矢量图层设置数据源
 * @param layerName
 * @param source
 */
C3GIS.prototype.setSourceForLayer = function (layerName,source) {
    var _this = this,layer = _this.getLayByName(layerName);
    if(layer != null){
        layer.setSource(source);
    }
}

/**
 * 更新矢量图层数据源
 * @param layerName
 * @param sourceUrl 新的数据地址
 * @param sourceOption 数据源附加参数对象，具有如下属性：
 *    spatialFilter：空间查询WKT参数
 * @param successCallBack 成功回调
 * @param errorCallBack 失败回调
 */
C3GIS.prototype.refreshVectorSource = function (layerName,sourceUrl,sourceOption,successCallBack,errorCallBack) {
    var _this = this,
        layer = _this.getLayByName(layerName),
        source;
    _this.closePopupWindow();
    _this.removeChartOverlay();
    if(layer == null) return;
    if(sourceUrl.indexOf('?') > 0){
        if(sourceUrl.indexOf('http') == 0){
            sourceUrl += '&date=' + (new Date()).valueOf();
        }else {
            sourceUrl += '&key=' + $.data(dataCache, 'key') + '&date=' + (new Date()).valueOf();
        }

    }else {
        if(sourceUrl.indexOf('http') == 0){
            sourceUrl += '?date=' + (new Date()).valueOf();
        }else {
            sourceUrl += '?key=' + $.data(dataCache, 'key') + '&date=' + (new Date()).valueOf();
        }
    }

    $.ajax({
        type: 'get',
        url: sourceUrl,
        dataType: 'json',
        success: function(data) {
            var featureArray = (new ol.format.GeoJSON()).readFeatures(data), resultArray = null,
                attr, attrArray = [];
            if(sourceOption != null
                && sourceOption.hasOwnProperty('spatialFilter')
                && sourceOption.spatialFilter != null){
                resultArray = [];
            }
            if(featureArray.length > 0){
                if(resultArray != null){
                    for(var i = 0,len = featureArray.length;i < len;i++){
                        if(sourceOption.spatialFilter.intersectsCoordinate(featureArray[i].getGeometry().getCoordinates())){
                            resultArray.push(featureArray[i]);

                            attr = featureArray[i].getProperties();
                            if(attr.hasOwnProperty('geometry')){
                                delete attr.geometry;
                            }
                            attrArray.push(attr);
                        }
                    }
                }else {
                    for(var i = 0,len = featureArray.length;i < len;i++){
                        attr = featureArray[i].getProperties();
                        if(attr.hasOwnProperty('geometry')){
                            delete attr.geometry;
                        }
                        attrArray.push(attr);
                    }
                }
            }

            source = layer.getSource();
            source.clear();

            source.addFeatures(featureArray);
            if(successCallBack != null){
                successCallBack(attrArray);
            }
            _this.zoomMapByVectorLayer(layerName,null);
        },
        error:function (error) {
            source = layer.getSource();
            source.clear();
            if(errorCallBack != null){
                errorCallBack(error)
            }
        }
    });
}

// 给图层设置supermap或arcgis FeatureService
C3GIS.prototype.setSource_featureService = function (layer,sourceType,sourceOptions) {
    if(sourceType === 'ol.supermap.FeatureService'
        && sourceOptions.hasOwnProperty('url')
        && sourceOptions['url'] != ''
        && sourceOptions.hasOwnProperty('datasource')
        && sourceOptions['datasource'] != ''
        && sourceOptions.hasOwnProperty('dataset')
        && sourceOptions['dataset'] != ''){
        var serviceParam,
            queryParameter={name: sourceOptions['dataset'] + '@' + sourceOptions['datasource']};
        queryParameter['attributeFilter'] = sourceOptions.hasOwnProperty('attributeFilter') && sourceOptions['attributeFilter'] != ''
            ? sourceOptions['attributeFilter']:'SMID >= 0';
        if(sourceOptions.hasOwnProperty('geometry') && sourceOptions['geometry'] != ''){
            serviceParam = new SuperMap.GetFeaturesByGeometryParameters({
                datasetNames: [sourceOptions['datasource'] + ':' + sourceOptions['dataset']],
                queryParameter: queryParameter,
                geometry: (new SuperMap.Format.WKT()).read(sourceOptions['geometry']).geometry,
                spatialQueryMode: "INTERSECT"
            });
            new ol.supermap.FeatureService(sourceOptions['url']).getFeaturesByGeometry(serviceParam,function (serviceResult) {
                var vectorSource = new ol.source.Vector({
                    features: (new ol.format.GeoJSON()).readFeatures(serviceResult.result.features),
                    wrapX: false
                });
                layer.setSource(vectorSource);
            });
        }else {
            serviceParam = new SuperMap.GetFeaturesBySQLParameters({
                queryParameter: queryParameter,
                datasetNames: [sourceOptions['datasource'] + ':' + sourceOptions['dataset']]
            });
            new ol.supermap.FeatureService(sourceOptions['url']).getFeaturesBySQL(serviceParam,function (serviceResult) {
                var vectorSource = new ol.source.Vector({
                    features: (new ol.format.GeoJSON()).readFeatures(serviceResult.result.features),
                    wrapX: false
                });
                layer.setSource(vectorSource);
            });
        }
    }else if(sourceType === 'arcgis.FeatureService'){

    }
}
C3GIS.prototype.setSourceForLayer_featureService = function (layerName,sourceType,sourceOptions) {
    var _this = this,layer = _this.getLayByName(layerName);
    if(layer != null){
        _this.setSource_featureService(layer,sourceType,sourceOptions);
    }
}

C3GIS.prototype.setStyleForVectoryLayer = function (layerName,style) {
    var _this = this,layer = _this.getLayByName(layerName);
    if(layer != null){
        layer.setStyle(style);
    }
}

/**
 * 根据图层编号隐藏图层
 * @param layerId
 */
C3GIS.prototype.hideLayerById = function (layerId) {
    var _this = this,selectedLayer = _this.getLayerById(layerId);
    if(selectedLayer != null && selectedLayer.getVisible()){
        selectedLayer.setVisible(false);
    }
}
C3GIS.prototype.removeLayerById =function (layerId) {
    var _this = this,selectedLayer = _this.getLayerById(layerId);
    if(selectedLayer != null){
        _this.mainMap.removeLayer(selectedLayer);
    }
}


/**
 * 根据图层名称隐藏图层
 * @param layerName
 */
C3GIS.prototype.hideLayerByName = function (layerName) {
    var _this = this,selectedLayer = _this.getLayByName(layerName);
    if(selectedLayer != null && selectedLayer.getVisible()){
        selectedLayer.setVisible(false);
    }
}

C3GIS.prototype.removeLayerByName =function (layerName) {
    var _this = this,selectedLayer = _this.getLayByName(layerName);
    if(selectedLayer != null){
        _this.mainMap.removeLayer(selectedLayer);
    }
}

C3GIS.prototype.removeLayerByType = function (layerType) {
    var _this = this,
        layerList = _this.mainMap.getLayers().getArray(),
        removingLayers = [],
        layerAttr;
    if(layerList.length > 0){
        for(var i = 0,len = layerList.length;i < len;i++){
            layerAttr = layerList[i].getProperties();
            if(layerAttr.hasOwnProperty('layerType') && layerAttr.layerType == layerType){
                removingLayers.push(layerList[i]);
            }
        }
        if(removingLayers.length > 0){
            for(var j = 0,jLen = removingLayers.length;j < jLen;j++){
                _this.mainMap.removeLayer(removingLayers[j]);
            }
        }
    }
}

/**
 * 根据图层编号显示图层
 * @param layerId
 */
C3GIS.prototype.showLayerById = function (layerId) {
    var _this = this,selectedLayer = _this.getLayerById(layerId);
    if(selectedLayer != null && !selectedLayer.getVisible()){
        selectedLayer.setVisible(true);
    }
}

/**
 * 根据图层名称显示图层
 * @param layerName
 */
C3GIS.prototype.showLayerByName = function (layerName) {
    var _this = this,selectedLayer = _this.getLayByName(layerName);
    if(selectedLayer != null && !selectedLayer.getVisible()){
        selectedLayer.setVisible(true);
    }
}

/**
 * 根据图层编号设置Zindex
 * @param layerId
 * @param zIndex
 */
C3GIS.prototype.setZIndexById = function (layerId,zIndex) {
    var _this = this,selectedLayer = _this.getLayerById(layerId);
    if(selectedLayer != null){
        selectedLayer.setZIndex(zIndex);
    }
}

/**F
 * 根据图层名称设置Zindex
 * @param layerName
 * @param zIndex
 */
C3GIS.prototype.setZIndexByName = function (layerName,zIndex) {
    var _this = this,selectedLayer = _this.getLayByName(layerName);
    if(selectedLayer != null){
        selectedLayer.setZIndex(zIndex);
    }
}

/**
 * 从服务器获取图层并加载数据
 * @param layerName 图层名，从支持系统获取
 * @param options 附加参数对象,其中可能的属性包括：
 *  1）isClear是否删除已存在的vector图层，默认为false不删除，true表示删除；
 *  2）callBack数据加载前的回调函数
 */
C3GIS.prototype.addLayerFromRemoteServer = function (layerName,options) {
    var _this = this, serverURL= _this.serverURL(),layerOptions;
    if(options == null){
        layerOptions = {
            isClear:false,
            callBack:null
        }
    }else {
        layerOptions = options;
        if(!layerOptions.hasOwnProperty('isClear')){
            layerOptions['isClear'] = false;
        }
        if(!layerOptions.hasOwnProperty('callBack')){
            layerOptions['callBack'] = null;
        }
    }
    $.ajax({
        type: 'get',
        url: serverURL + 'api/ol/layer/layerentry?layername=' + layerName + '&key=' + $.data(dataCache, 'key'),
        dataType: 'json',
        async: false,
        success: function(data) {
            if(layerOptions.isClear){
                _this.removeLayerByType('ol.layer.Vector');
            }

            if(data == null || !data.hasOwnProperty('layer') || data['layer'] == null) return;

            if(data.hasOwnProperty('source') && data['source'] != null){
                if(data['source']['type'] != 'ol.supermap.FeatureService'
                    && data['source']['type'] != 'arcgis.FeatureService'){
                    if(data['layer']['type'] == 'ol.layer.Vector'){
                        if(data['layer']['options'].hasOwnProperty('successCallBack')
                            && data['layer']['options']['successCallBack']['code'] != ''){
                            data['source']['options']['successCallBack']
                                = eval("("+ data['layer']['options']['successCallBack']['code'] +")");
                        }
                        if(data['layer']['options']['errorCallBack'].hasOwnProperty('errorCallBack')
                            && data['layer']['options']['errorCallBack']['code'] != ''){
                            data['source']['options']['errorCallBack']
                                = eval("("+ data["layer"]['options']['errorCallBack']['code'] +")");
                        }
                    }
                    data['layer']['source']
                        = _this.createSourceByType(data['source']['type'],data['source']['options']);
                }else {
                    data['layer']['source'] = data['source'];
                }
                //添加图层
                _this.addLayer(data['layer']["type"],data['layer']["layerName"],data['layer']);

                if(layerOptions.callBack != null){
                    layerOptions.callBack();
                }
                //按图层Extent缩放地图
                _this.zoomMapByVectorLayer(data['layer']["layerName"],null);
            }
        },
        error:function (error) {
            callBack();
            console.log(error);
        }
    });
}

/**
 * 从矢量图层中查询符合条件的要素
 * @param layerName 图层名称
 * @param filterFunc 判断函数，形如function(feature){ ... return true/false}
 * @returns {*} f返回符合条件的要素数组
 */
C3GIS.prototype.filterFeatureFromVectorLayer = function (layerName,filterFunc) {
    var resultFeatures = [];
    if(layerName == null || layerName == ""
        || checkFunc == null || Object.propotype.toString.call(filterFunc) != "[object Function]") return resultFeatures;
    var _this = this, queryLayer = _this.getLayByName(layerName);
    if(queryLayer != null && queryLayer.getSource.getFeatures().length > 0){
        var features = queryLayer.getSource.getFeatures();
        for(var i = 0,len = features.length;i < len;i++){
            if(filterFunc(features[i])){
                resultFeatures.push(features[i]);
            }
        }
    }
    return resultFeatures;
}

C3GIS.prototype.filterFeatureByPolygon = function (polygon) {
    var _this = this, drawLayer = _this.getLayByName('drawLayer');
    if(polygon == null || drawLayer == null) return;

}
/**********************************layer end*****************************************/



/**********************************source start*****************************************/
C3GIS.prototype.createSourceByType = function (sourceType,sourceOption) {
    var source = null;
    if(sourceType == null || sourceType == "") return source;
    switch(sourceType){
        case "ol.source.WMTS":
            var projection = ol.proj.get(sourceOption.hasOwnProperty("projection")?sourceOption.projection:"EPSG:4326"),
                projectionExtent = projection.getExtent(),
                size = ol.extent.getWidth(projectionExtent)/256,
                resolutions = new Array(20),
                matrixIds = new Array(14);
            for(var z = 0;z < 20;z++){
                resolutions[z] = size/Math.pow(2,z);
                matrixIds[z] = z;
            }
            source = new ol.source.WMTS({
                url:sourceOption.url,
                layer:sourceOption.layer,
                format:sourceOption.format,
                tileGrid:new ol.tilegrid.WMTS({
                    origin: ol.extent.getTopLeft(projectionExtent),
                    resolutions: resolutions,
                    matrixIds: matrixIds
                }),
                matrixSet:sourceOption.matrixSet,
                style: sourceOption.style
            });
            break;
        case "ol.source.TileArcGISRest":
            source = new ol.source.TileArcGISRest({
                url:sourceOption.url
            });
            break;
        case "ol.source.TileSuperMapRest":
            source = new ol.source.TileSuperMapRest({
                url:sourceOption.url,
                transparent:true,
                wrapX: true
            });
            break;
        case "ol.source.Vector":
            var vectorPrototype = {};
            if(sourceOption.hasOwnProperty("url") && sourceOption.url != null){
                var sourceUrl = sourceOption.url;
                if(sourceUrl.indexOf('?') > 0){
                    if(sourceUrl.indexOf('http') == 0){
                        sourceUrl += '&date=' + (new Date()).valueOf();
                    }else {
                        sourceUrl += '&key=' + $.data(dataCache, 'key') + '&date=' + (new Date()).valueOf();
                    }

                }else {
                    if(sourceUrl.indexOf('http') == 0){
                        sourceUrl += '?date=' + (new Date()).valueOf();
                    }else {
                        sourceUrl += '?key=' + $.data(dataCache, 'key') + '&date=' + (new Date()).valueOf();
                    }
                }
                //获取后台空间数据
                $.ajax({
                    type: 'get',
                    url: sourceUrl,
                    dataType: 'json',
                    async: false,
                    success: function(data) {
                        if(data == null) return;
                        var featureArray = (new ol.format.GeoJSON()).readFeatures(data),resultArray = null,
                            attr, attrArray = [];
                        if(sourceOption.hasOwnProperty('spatialFilter')
                            && sourceOption.spatialFilter != null){
                            resultArray = [];
                        }
                        if(featureArray.length > 0){
                            if(resultArray != null){
                                for(var i = 0,len = featureArray.length;i < len;i++){
                                    // 空间筛选
                                    if(sourceOption.spatialFilter.intersectsCoordinate(featureArray[i].getGeometry().getCoordinates())){
                                        resultArray.push(featureArray[i]);

                                        attr = featureArray[i].getProperties();
                                        if(attr.hasOwnProperty('geometry')){
                                            delete attr.geometry;
                                        }
                                        attrArray.push(attr);
                                    }
                                }
                            }else {
                                for(var i = 0,len = featureArray.length;i < len;i++){
                                    attr = featureArray[i].getProperties();
                                    if(attr.hasOwnProperty('geometry')){
                                        delete attr.geometry;
                                    }
                                    attrArray.push(attr);
                                }
                            }
                        }
                        source = new ol.source.Vector({
                            features: resultArray != null ? resultArray : featureArray
                        });
                        if(sourceOption.hasOwnProperty("successCallBack")
                            && sourceOption.successCallBack != undefined
                            && sourceOption.successCallBack != null){
                            sourceOption.successCallBack(attrArray);
                        }
                    },
                    error:function (error) {
                        if(sourceOption.hasOwnProperty("errorCallBack")
                            && sourceOption.errorCallBack != undefined
                            && sourceOption.errorCallBack != null){
                            sourceOption.errorCallBack(error);
                        }
                    }
                });


            }else if(sourceOption.hasOwnProperty("features")
                && Object.prototype.toString.call(sourceOption.features) == "[object Array]"){
                source = new ol.source.Vector({
                    features: sourceOption.features
                });
                if(sourceOption.hasOwnProperty("successCallBack")){
                    eval("("+ sourceOption.successCallBack +")")
                }
            }
            break;
    }
    return source;
}

/**
 * 根据feature数组生成数据源
 * @param features
 * @returns {*}
 */
C3GIS.prototype.createSourceByFeatures = function (features) {
    if(features == null) return null;
    return new ol.source.Vector({
        features: features
    });
}

C3GIS.prototype.createSourceByGeojson = function(geojsonObject){
    if(geojsonObject == null) return null;
    return new ol.source.Vector({
        features: (new ol.format.GeoJSON()).readFeatures(geojsonObject)
    });
}
/**********************************source end******************************************/





/**********************************overlay start*****************************************/
/**
 * 生成并显示浮动窗
 * @param popupOptions，参数对象属性如下：
 * themesClass：主题类，主类名和主题类名，枚举：black/gray
 * toolArray：按钮属性数组，属性如下：id（按钮<a>标签的id）、onclick（单击回调函数）、src（按钮图标地址）、text（按钮文字）
 * height：浮动窗高度
 * width：浮动窗宽度
 * url：浮动窗内嵌网页地址
 * coordinate：浮动窗位置，形如[120, 38]
 */
C3GIS.prototype.createPopup = function (popupOptions) {
    var _this = this;
    //浮动窗头部——关闭按钮
    var themesClass = popupOptions.hasOwnProperty("themesClass")
        && popupOptions["themesClass"] != null
        && popupOptions["themesClass"] != ""
            ? popupOptions["themesClass"] : "black",
        popupHeader = "<a href='' id='popup-closer' class='ol-popup-closer ol-popup-closer_";
    popupHeader += themesClass;
    popupHeader += "'></a>";

    //浮动窗头部——功能按钮
    popupHeader += "<div class='pop_title pop_title_" + themesClass;
    popupHeader += "'><div class='title_left title_left_" + themesClass;
    popupHeader += "'>"
    if(popupOptions.hasOwnProperty("toolArray")
        && popupOptions["toolArray"] != null
        && popupOptions["toolArray"].length > 0){
        popupHeader += "<ul>";
        for(var i = 0,len = popupOptions["toolArray"].length;i < len;i++){
            popupHeader += "<li><a href='#' id='"
                + popupOptions["toolArray"][i]["id"]
                + "' onclick='" + popupOptions["toolArray"][i]["onclick"]
                + "'><img src='" + popupOptions["toolArray"][i]["src"] + "'" + " width='16px' height='16px'>"
                + popupOptions["toolArray"][i]["text"] + "</a></li>";
        }
        popupHeader += "</ul>";
    }
    popupHeader += "</div></div>";

    var popupContent = "<div id='popup-content'>";
    popupContent += "<iframe id='myiframe' class='myiframe' name='myiframe' style='width:100%;overflow:-Scroll;overflow-x:hidden' marginwidth='0' marginheight='0' height='";
    popupContent += popupOptions['height'] + "px' hspace='0' vspace='0' frameborder='0' allowtransparency='true' src='";
    popupContent += popupOptions['url'] + "'></iframe>"

    //_this.reinitIframe('myiframe',popupOptions['height']);
    // window.setTimeout("gis.reinitIframe('myiframe'," + popupOptions['height'] + ")", 200);
    popupContent += "</div>";

    var popupDiv = document.getElementById("popup");

    popupDiv.innerHTML = popupHeader + popupContent;
    popupDiv.style.setProperty("min-width",popupOptions["width"] + "px");
    _this.popupOverlay.setElement(popupDiv);
    _this.popupOverlay.setPosition(popupOptions['coordinate']);

    popupDiv.setAttribute("class", "ol-popup ol-popup_" + themesClass);

    document.getElementById('popup-closer').onclick = function () {
        _this.popupOverlay.setPosition(undefined);
        this.blur();
        return false;
    };
}
C3GIS.prototype.reinitIframe = function (iframeId, maxheight) {
    var iframe = document.getElementById(iframeId);
    try {
        var iframeWin = iframe.contentWindow || iframe.contentDocument.parentWindow;
        if (iframeWin.document.body) {
            var scrollHeight = iframeWin.document.documentElement.scrollHeight || iframeWin.document.body.scrollHeight;
            if((maxheight == '' || maxheight == 0) && scrollHeight > 400)
                scrollHeight = 400;
            else if(maxheight != '' && maxheight != 0 && scrollHeight > maxheight)
                scrollHeight = maxheight;
            iframe.height = scrollHeight + 20;
        }
        $(iframe).contents().find("body").css({'overflow': '-Scroll', 'overflow-x': 'hidden'});//去除横向滚动条，存在跨域问题，需部署在服务器上测试
    } catch (ex) {
        console.log('reinitIframe error:' + ex);
    }
}
C3GIS.prototype.closePopupWindow = function () {
    var _this = this;
    _this.popupOverlay.setPosition(undefined);
    //_this.blur();
    return false;
}

/**
 * 生成Overlay
 * @param divId Overlay对于的div id值
 * @param coordinate Overlay对应的中心点
 * @param overlayOptions 可选参数，其中包括
 *    class：div对应的class
 *    callBack：生成Overlay后的回调函数
 */
C3GIS.prototype.createOverlay = function (divId,coordinate,overlayOptions) {
    if(divId == null || divId == '' || coordinate == null) return;
    var _this = this,
        overlayDiv = document.createElement("div"),
        overlay;
    overlayDiv.setAttribute("id", divId);
    if(overlayOptions != null && overlayOptions.hasOwnProperty('class')){
        overlayDiv.setAttribute("class", overlayOptions["class"]);
    }

    overlay = new ol.Overlay({
        id:divId,
        position: coordinate,
        positioning: 'center-center',
        element: overlayDiv
    });
    _this.mainMap.addOverlay(overlay);

    if(overlayOptions != null && overlayOptions.hasOwnProperty('callBack')){
        overlayOptions.callBack(overlayDiv);
    }
}
/**
 * 删除除去popup的所有Overlays
 */
C3GIS.prototype.removeOverlay = function () {
    var _this = this, overlays = gis.mainMap.getOverlays(),
        overlayArray, overlayId,deleteOverlays = [];

    if(overlays != undefined && overlays.getLength() > 0){
        overlayArray = overlays.getArray();
        for(var i = 0,len = overlayArray.length;i < len;i++){
            overlayId = overlayArray[i].getId();
            if(overlayId != "popup"){
                deleteOverlays.push(overlayArray[i]);
            }
        }
        if(deleteOverlays.length > 0){
            for(var i = 0,len = deleteOverlays.length;i < len;i++){
                _this.mainMap.removeOverlay(deleteOverlays[i]);
            }
        }
    }
}
/**
 * 生成chartOverlay的数组参数，每个元素是其中一个Overlay的参数对象，其中具有如下属性：
 *  chartOption echarts图标参数
 *  reginCode 图标所在行政区编号
 *  reginPoint 行政区所在中心点
 * @param charOptions
 */
C3GIS.prototype.createChartOverlay = function (charOptions) {
    var _this = this,reginCode,chartDiv,pie;
    if(charOptions == null || charOptions.length == 0) return;
    for(var i = 0,len = charOptions.length;i < len;i++){
        if(!charOptions[i].hasOwnProperty('reginPoint') || charOptions[i]['reginPoint'] == undefined) continue;

        reginCode = charOptions[i]['reginCode'];
        chartDiv = document.createElement("div");
        chartDiv.setAttribute("id", reginCode);
        chartDiv.setAttribute("class", "chart");
        pie = new ol.Overlay({
            id:"chart_" + reginCode,
            position: charOptions[i]['reginPoint'],
            positioning: 'center-center',
            element: chartDiv
        });
        _this.mainMap.addOverlay(pie);
        echarts.init(chartDiv).setOption(charOptions[i]['chartOption']);
    }
}

/**
 * 为矢量图层元素添加闪烁效果
 * @param layerName 图层名称
 * @param chechedFunc 判断函数
 */
C3GIS.prototype.addFlashOverlay = function (layerName,chechedFunc) {
    if(layerName == null || layerName == '' || chechedFunc == null) return;
    var _this = this, selectedLayer = _this.getLayByName(layerName),
        features, attributes, overlayDiv, flashOverlay;

    if(selectedLayer != null && selectedLayer.getSource().getFeatures().length > 0){
        features = selectedLayer.getSource().getFeatures();
        for(var i = 0,len = features.length;i < len;i++){
            attributes = features[i].getProperties();
            if(chechedFunc(attributes)){
                overlayDiv = document.createElement('div');
                overlayDiv.classList.add('css_animation');
                flashOverlay = new ol.Overlay({
                    id:"flash_" + i,
                    element: overlayDiv,
                    positioning: 'center-center',
                    offset:[0,10],
                    stopEvent:false
                });
                flashOverlay.setPosition(features[i].getGeometry().getCoordinates());
                _this.mainMap.addOverlay(flashOverlay);
            }
        }
    }

}

/**
 * 删除所有Overlay
 */
C3GIS.prototype.removeChartOverlay = function () {
    var _this = this,selectedOverlay,overlayId,deleteOverlays = [];
    selectedOverlay = _this.mainMap.getOverlays().getArray();
    if(selectedOverlay.length > 0){
        for(var i = 0,len = selectedOverlay.length;i < len;i++){
            overlayId = selectedOverlay[i].getId();
            if(overlayId != null
                && (overlayId.indexOf('chart') == 0 || overlayId.indexOf('flash') == 0)){
                deleteOverlays.push(selectedOverlay[i]);

            }
        }
        if(deleteOverlays.length > 0){
            for(var i = 0,len = deleteOverlays.length;i < len;i++){
                _this.mainMap.removeOverlay(deleteOverlays[i])
            }
        }
    }
}
/**********************************overlay end*****************************************/


/**********************************style start*****************************************/
/**
 * 生成文字样式
 * @param text 显示的文字内容
 * @param styleOptions 样式可选参数
 * @returns {ol.style.Text}
 */
C3GIS.prototype.createTextStyle = function (text,styleOptions) {
    var styleParams,
        textStr = text == null?'':text;
    if(styleOptions != null){
        styleParams = styleOptions;
    }else {
        styleParams = null;
    }
    if(!styleParams.hasOwnProperty('offsetY')){
        //字体垂直方向上的偏移
        styleParams.offsetY = -24;
    }
    if(!styleParams.hasOwnProperty('font')){
        //字体与大小
        styleParams.font = '16px Microsoft YaHei Bold';
    }
    if(!styleParams.hasOwnProperty('backgroundFill')){
        styleParams.backgroundFill = '#2b81ff';
    }
    if(!styleParams.hasOwnProperty('backgroundStroke_color')){
        styleParams.backgroundStroke_color = '#2b81ff';
    }
    if(!styleParams.hasOwnProperty('backgroundStroke_width')){
        styleParams.backgroundStroke_width = 5;
    }
    if(!styleParams.hasOwnProperty('fill')){
        //文字填充色
        styleParams.fill = '#fff';
    }

    return new ol.style.Text({
        offsetY:styleParams.offsetY,
        font: styleParams.font,
        backgroundFill: new ol.style.Fill({
            color: styleParams.backgroundFill
        }),
        backgroundStroke: new ol.style.Stroke({
            color: styleParams.backgroundStroke_color,
            width: styleParams.backgroundStroke_width
        }),
        fill: new ol.style.Fill({
            color: styleParams.fill
        }),
        stroke: new ol.style.Stroke({//文字边界宽度与颜色
            color: '#000',
            width: 3
        }),
        text:textStr
    })
}


/**********************************style end*******************************************/


/**********************************common end*****************************************/
/**
 * @param x - {Float}
 * @returns {Float}
 */
C3GIS.prototype.rad = function(x) {return x*Math.PI/180;};

C3GIS.prototype.deg = function(x) {return x*180/Math.PI;};

/**
 * 根据传入的起始点计算目标点的经纬度(度)、角方向（度）和距离(米)。
 *
 * Parameters:
 * lonlat  - {<SuperMap.LonLat>} (或者带有经纬度属性的任何对象)起点。
 * brng  - {Float} 角方向(度)。
 * dist  - {Float} 距离(米)。
 *
 * Returns:
 * {Float} 目标点。
 */
C3GIS.prototype.destinationVincenty = function(lon, lat, brng, dist) {
    var _this = this,
        s = dist,
        alpha1 = _this.rad(brng),
        sinAlpha1 = Math.sin(alpha1),
        cosAlpha1 = Math.cos(alpha1),
        ct = {
            a: 6378137,
            b: 6356752.3142,
            f: 1/298.257223563
        };
    var a = ct.a, b = ct.b, f = ct.f;

    var tanU1 = (1-f) * Math.tan(_this.rad(lat));
    var cosU1 = 1 / Math.sqrt((1 + tanU1*tanU1)),
        sinU1 = tanU1*cosU1;
    var sigma1 = Math.atan2(tanU1, cosAlpha1);
    var sinAlpha = cosU1 * sinAlpha1;
    var cosSqAlpha = 1 - sinAlpha*sinAlpha;
    var uSq = cosSqAlpha * (a*a - b*b) / (b*b);
    var A = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));
    var B = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)));

    var sigma = s / (b*A), sigmaP = 2*Math.PI;
    while (Math.abs(sigma-sigmaP) > 1e-12) {
        var cos2SigmaM = Math.cos(2*sigma1 + sigma);
        var sinSigma = Math.sin(sigma);
        var cosSigma = Math.cos(sigma);
        var deltaSigma = B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-
            B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));
        sigmaP = sigma;
        sigma = s / (b*A) + deltaSigma;
    }

    var tmp = sinU1*sinSigma - cosU1*cosSigma*cosAlpha1;
    var lat2 = Math.atan2(sinU1*cosSigma + cosU1*sinSigma*cosAlpha1,
        (1-f)*Math.sqrt(sinAlpha*sinAlpha + tmp*tmp));
    var lambda = Math.atan2(sinSigma*sinAlpha1, cosU1*cosSigma - sinU1*sinSigma*cosAlpha1);
    var C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));
    var L = lambda - (1-C) * f * sinAlpha *
        (sigma + C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));

    var revAz = Math.atan2(sinAlpha, -tmp);

    var newLon = _this.deg(L),
        newLat = _this.deg(lat2) -lat;

    return Math.sqrt(Math.pow(newLat, 2) + Math.pow(newLon, 2));
}
/**********************************common end*****************************************/


/**********************************bussiness start*****************************************/
C3GIS.prototype.getAirIconByLevel= function (airLevel) {
    var _this = this,url = _this.serverURL();
    switch(airLevel){
        case "Ⅰ":
            url += "static/spatial/images/air/1.png";
            break;
        case "Ⅱ":
            url += "static/spatial/images/air/2.png";
            break;
        case "Ⅲ":
            url += "static/spatial/images/air/3.png";
            break;
        case "Ⅳ":
            url += "static/spatial/images/air/4.png";
            break;
        case "Ⅴ":
            url += "static/spatial/images/air/5.png";
            break;
        case "Ⅵ":
            url += "static/spatial/images/air/6.png";
            break;
        default:
            url += "static/spatial/images/air/7.png";
            break;
    }
    return url;
}

C3GIS.prototype.getAirIconByAQI= function (airAQI) {
    var _this = this,url = _this.serverURL();
    switch(true){
        case airAQI <= 50:
            url += "static/spatial/images/air/1.png";
            break;
        case airAQI > 50 && airAQI <= 100:
            url += "static/spatial/images/air/2.png";
            break;
        case airAQI > 100 && airAQI <= 150:
            url += "static/spatial/images/air/3.png";
            break;
        case airAQI > 150 && airAQI <= 200:
            url += "static/spatial/images/air/4.png";
            break;
        case airAQI > 200 && airAQI <= 300:
            url += "static/spatial/images/air/5.png";
            break;
        case airAQI > 300:
            url += "static/spatial/images/air/6.png";
            break;
        default:
            url += "static/spatial/images/air/7.png";
            break;
    }
    return url;
}

C3GIS.prototype.getEnterpriseIconByType= function (enterpriseType) {
    var _this = this,url = _this.serverURL() + "static/spatial/images/enterprise/";

    if (enterpriseType == null || enterpriseType == "") {
        url += "0.png";
        return url;
    }

    if (enterpriseType.indexOf('31') == 0) {
        url += "31.png";
    } else if (enterpriseType.indexOf('4411') == 0 || enterpriseType.indexOf('44') == 0) {
        url += "44.png";
    } else if (enterpriseType.indexOf('19') == 0) {
        url += "19.png";
    }
    else if (enterpriseType.indexOf('30') == 0) {
        url += "30.png";
    }
    else if (enterpriseType.indexOf('07') == 0 || enterpriseType.indexOf('26') == 0) {
        url += "26.png";
    }
    else if (enterpriseType.indexOf('32') == 0) {
        url += "32.png";
    } else if (enterpriseType.indexOf('22') == 0) {
        url += "22.png";
    } else if (enterpriseType.indexOf('17') == 0) {
        url += "17.png";
    } else if (enterpriseType.indexOf('25') == 0) {
        url += "25.png";
    }
    else if (enterpriseType.indexOf('4620') == 0) {
        url += "zc_wsc.png";
    }
    else {
        url += "0.png";
    }
    return url;
}

/**
 * 根据气象信息获取具体的风向图
 * @param sd：风速
 * @param fx：风向
 * @returns {string}
 */
C3GIS.prototype.getQxPiecture = function (sd, fx) {
    var _this = this,url = _this.serverURL() + "static/spatial/images/weather/"
    var dj, fxStr, fxIndex;
    switch (true) {
        case sd >= 0 && sd <= 0.2:
            dj = 0;
            break;
        case sd > 0.2 && sd <= 1.5:
            dj = 1;
            break;
        case sd > 1.5 && sd <= 3.3:
            dj = 2;
            break;
        case sd > 3.3 && sd <= 5.4:
            dj = 3;
            break;
        case sd > 5.4 && sd <= 7.9:
            dj = 4;
            break;
        case sd > 7.9 && sd <= 10.7:
            dj = 5;
            break;
        case sd > 10.7 && sd <= 13.8:
            dj = 6;
            break;
        case sd > 13.8 && sd <= 17.1:
            dj = 7;
            break;
        case sd > 17.1 && sd < 20.7:
            dj = 8;
            break;
        case sd > 20.7 && sd <= 24.4:
            dj = 9;
            break;
        case sd > 24.4 && sd <= 28.4:
            dj = 10;
            break;
        case sd > 28.4 && sd <= 32.6:
            dj = 11;
            break;
        case sd > 32.6:
            dj = 12;
            break;
    }

    if (fx.length > 2) {
        fxStr = fx.substr(0, 2);
    } else {
        fxStr = fx;
    }

    switch (true) {
        case fxStr == "北":
            fxIndex = 1;
            break;
        case fxStr == "东北":
            fxIndex = 2;
            break;
        case fxStr == "东":
            fxIndex = 3;
            break;
        case fxStr == "东南":
            fxIndex = 4;
            break;
        case fxStr == "南":
            fxIndex = 5;
            break;
        case fxStr == "西南":
            fxIndex = 6;
            break;
        case fxStr == "西":
            fxIndex = 7;
            break;
        case fxStr == "西北":
            fxIndex = 8;
            break;
    }

    return url + "w" + dj + "_" + fxIndex + ".png";
}

/**
 * 根据风向和风速生成用于缓冲区分析的先
 * @param statrtPoint 起始点
 * @param direction 风向
 * @param speed 风速
 */
C3GIS.prototype.createLineByDirectionSpeed = function (startLon, startLat, direction, speed) {
    if (startLon == null || startLat == null || direction == null || speed == null) {
        return null;
    }
    var _this = this,
        rawvalue = { x:startLon, y:startLat },
        resultValue;
    switch (true) {
        case direction == "南":
            resultValue = _this.getOffsetValue(rawvalue,
                { "x": 0, "y": 1 });
            break;
        case direction == "东北偏北":
            resultValue = _this.getOffsetValue(rawvalue,
                { "x": 0.382683432365089, "y": 0.923879532511286 });
            break;
        case direction == "东北":
            resultValue = _this.getOffsetValue(rawvalue,
                { "x": 0.707106781186547, "y": 0.707106781186547 });
            break;
        case direction == "东北偏东":
            resultValue = _this.getOffsetValue(rawvalue,
                { "x": 0.923879532511286, "y": 0.382683432365089 });
            break;
        case direction == "东":
            resultValue = _this.getOffsetValue(rawvalue,
                { "x": 1, "y": 0 });
            break;
        case direction == "东南偏东":
            resultValue = _this.getOffsetValue(rawvalue,
                { "x": 0.923879532511286, "y": -0.382683432365089 });
            break;
        case direction == "东南":
            resultValue = _this.getOffsetValue(rawvalue,
                { "x": 0.707106781186547, "y": -0.707106781186547 });
            break;
        case direction == "东南偏南":
            resultValue = _this.getOffsetValue(rawvalue,
                { "x": 0.382683432365089, "y": -0.923879532511286 });
            break;
        case direction == "北":
            resultValue = _this.getOffsetValue(rawvalue,
                { "x": 0, "y": -1 });
            break;
        case direction == "西南偏南":
            resultValue = _this.getOffsetValue(rawvalue,
                { "x": -0.382683432365089, "y": -0.923879532511286 });
            break;
        case direction == "西南":
            resultValue = _this.getOffsetValue(rawvalue,
                { "x": -0.707106781186547, "y": -0.707106781186547 });
            break;
        case direction == "西南偏西":
            resultValue = _this.getOffsetValue(rawvalue,
                { "x": -0.923879532511286, "y": -0.382683432365089 });
            break;
        case direction == "西":
            resultValue = _this.getOffsetValue(rawvalue,
                { "x": -1, "y": 0 });
            break;
        case direction == "西北偏西":
            resultValue = _this.getOffsetValue(rawvalue,
                { "x": -0.923879532511286, "y": 0.382683432365089 });
            break;
        case direction == "西北":
            resultValue = _this.getOffsetValue(rawvalue,
                { "x": -0.707106781186547, "y": 0.707106781186547 });
            break;
        case direction == "西北偏北":
            resultValue = _this.getOffsetValue(rawvalue,
                { "x": -0.382683432365089, "y": 0.923879532511286 });
            break;
    }
    return [resultValue.x,resultValue.y];
}
C3GIS.prototype.getOffsetValue=function (rawValue, osValue) {
    var resultValue = {};
    resultValue.x = rawValue.x * (1 + osValue.x * 0.002);
    resultValue.y = rawValue.y * (1 + osValue.y * 0.002);

    return resultValue;
}
/**
 * 空气站点大气点位监察
 * @param airStation 空气站点属性对象，可以从空气站点列表获取或属性与空气站点列表属性一致并添加风向、风速属性
 *  direction：风向（可选）
 *  speed：风速（可选）
 * @param bufferOptions 缓冲区分析参数对象，具有如下属性：
 *  distance: 缓冲区半径，单位是米（必选）
 *  controlLevels：废气企业控制级别，形如1,2,3（可选）
 *  successCallBack:数据成功回调函数（可选）
 *  errorCallBack：数据失败回调函数（可选）
 *  clickCallBack:点击事件,形如function(property){...}
 */
C3GIS.prototype.bufferEnterpriseByAirStation = function (airStation, bufferOptions) {
    if(airStation == null
        || !airStation.hasOwnProperty("longitude")
        || !airStation.hasOwnProperty("latitude")
        || !airStation.hasOwnProperty("level")){
        return;
    }
    if(bufferOptions == null || !bufferOptions.hasOwnProperty("distance")){
        return;
    }
    var _this = this,
        spatialDis =_this.destinationVincenty(airStation.longitude,airStation.latitude,45,bufferOptions.distance),
        serverURL = _this.serverURL(),
        endCoordinate = null,
        url = serverURL
            + 'api/datacenter/wastegas/bufferenterprises?key='
            +$.data(dataCache, 'key')
            + '&startlon=' +airStation.longitude
            + '&startlat='+ airStation.latitude
            + '&distance='+bufferOptions.distance
            +'&spatialdis='+spatialDis;
    if(airStation.hasOwnProperty('direction') && airStation.hasOwnProperty('speed')){
        endCoordinate = _this.createLineByDirectionSpeed(
            airStation.longitude,airStation.latitude,airStation.direction,airStation.speed);
        url += '&endlon=' + endCoordinate[0] + '&endlat=' + endCoordinate[1];
    }
    $.ajax({
        type: 'get',
        url:url,
        success: function(data) {
            if(data == null
                || !data.hasOwnProperty('enterpriseList')
                || !data.hasOwnProperty('bufferWKT')){
                return;
            }
            //获取企业数据
            var enterpriseList = JSON.parse(data.enterpriseList);
            var resultFeatures =(new ol.format.GeoJSON()).readFeatures(enterpriseList);
            //获取缓冲区
            resultFeatures.push((new ol.format.WKT()).readFeature(data.bufferWKT));
            //添加空气站点
            var airFeature = new ol.Feature(new ol.geom.Point([airStation.longitude,airStation.latitude]));
            airFeature.setProperties(airStation);
            resultFeatures.push(airFeature);

            //添加气象标识点
            if(endCoordinate != null){
                var endFeature = new ol.Feature(new ol.geom.Point(endCoordinate));
                endFeature.setProperties({'type':'qx'});
                resultFeatures.push(endFeature);
            }
            //生成图层数据源
            var resultSource = new ol.source.Vector({
                features: resultFeatures
            });

            //判断图层是否存在，如果图层已经存在则只重置数据源
            var resultLayer = _this.getLayByName('airBufferLayer');
            if(resultLayer != null){
                resultLayer.setSource(resultSource);
                if(resultSource.getFeatures().length > 1){
                    _this.mainMap.getView().fit(resultSource.getExtent(), {
                        size: _this.mainMap.getSize(),
                        duration:_this.duration
                    });
                }else if(resultSource.getFeatures().length == 1){
                    _this.mainMap.getView().animate({
                        center:resultSource.getFeatures()[0].getGeometry().getCoordinates(),
                        duration:_this.duration
                    });
                }

                //设置属性数据的回调
                if(bufferOptions != null && bufferOptions.hasOwnProperty('successCallBack')){
                    bufferOptions.successCallBack(enterpriseList);
                }
                return;
            }
            //生成图层
            resultLayer = new ol.layer.Vector({
                source: resultSource,
                style:function (feature) {
                    var geometryType = feature.getGeometry().getType();
                    if (geometryType.toUpperCase() == "POLYGON") {
                        return new ol.style.Style({
                            stroke: new ol.style.Stroke({
                                color: 'blue',
                                width: 1
                            }),
                            fill: new ol.style.Fill({
                                color: 'rgba(255, 255, 0, 0.1)'
                            })
                        })
                    }else if (geometryType.toUpperCase() == "POINT"){
                        var property = feature.getProperties();
                        if(property.hasOwnProperty('level')){
                            //空气站点样式
                            return new ol.style.Style({
                                image: new ol.style.Icon(({
                                    src:_this.getAirIconByLevel(property.level)
                                }))
                            })
                        }else if(property.hasOwnProperty('type')){
                            //气象标识样式
                            return new ol.style.Style({
                                image: new ol.style.Icon(({
                                    src:_this.getQxPiecture(airStation.speed,airStation.direction)
                                }))
                            })
                        }
                        //企业点
                        return new ol.style.Style({
                            image: new ol.style.Icon(({
                                src:_this.getEnterpriseIconByType(property["industryCode"])
                            }))
                        })
                    }
                }
            });
            //设置图层名称
            resultLayer.setProperties({'name':'airBufferLayer','layerType':'ol.layer.Vector'});
            _this.mainMap.addLayer(resultLayer);


            var pointerMove = {
                    pointerMoveStyle:function (feature) {
                        var geometryType = feature.getGeometry().getType();
                        if (geometryType.toUpperCase() == "POLYGON") {
                            //缓冲区面的悬浮样式
                            return new ol.style.Style({
                                stroke: new ol.style.Stroke({
                                    color: 'blue',
                                    width: 1
                                }),
                                fill: new ol.style.Fill({
                                    color: 'rgba(255, 255, 0, 0.1)'
                                })
                            })
                        }else if (geometryType.toUpperCase() == "POINT"){
                            var property = feature.getProperties();
                            if(property.hasOwnProperty('level')){
                                //空气站点悬浮样式
                                return new ol.style.Style({
                                    image: new ol.style.Icon(({
                                        src:_this.getAirIconByLevel(property.level)
                                    }))
                                })
                            }else if(property.hasOwnProperty('type')){
                                //气象标识的悬浮样式
                                return new ol.style.Style({
                                    image: new ol.style.Icon(({
                                        src:_this.getQxPiecture(airStation.speed,airStation.direction)
                                    }))
                                })
                            }
                            //企业点悬浮事件
                            return new ol.style.Style({
                                image: new ol.style.Icon(({
                                    src:_this.getEnterpriseIconByType(property["industryCode"])
                                })),
                                text:new ol.style.Text({
                                    offsetY:-24,
                                    font: '16px Microsoft YaHei Bold',    //字体与大小
                                    backgroundFill: new ol.style.Fill({
                                        color: '#2b81ff'
                                    }),
                                    backgroundStroke: new ol.style.Stroke({
                                        color: '#2b81ff',
                                        width: 5
                                    }),
                                    fill: new ol.style.Fill({    //文字填充色
                                        color: '#fff'
                                    }),
                                    stroke: new ol.style.Stroke({    //文字边界宽度与颜色
                                        color: '#000',
                                        width: 3
                                    }),

                                    text:feature.get('enterpriseName')
                                })
                            })
                        }
                    }
                },
                click = {
                    clickCallBack:function(e) {
                        var arr=e.target;
                        var collection = arr.getFeatures();
                        var features = collection.getArray();
                        if(features.length > 0){
                            var geometryType,stationAttr;
                            for(var i = 0,len = features.length;i < len;i++){
                                geometryType = features[i].getGeometry().getType();
                                if(geometryType.toUpperCase() == "POLYGON") continue;
                                stationAttr = features[i].getProperties();
                                if(stationAttr.hasOwnProperty('enterpriseCode')
                                    && bufferOptions != null
                                    &&  bufferOptions.hasOwnProperty('clickCallBack')){
                                    bufferOptions.clickCallBack(stationAttr);
                                    break;
                                }
                            }
                        }
                    }
                };
            _this.addInteractionForVectorLayer('airBufferLayer',pointerMove,click);
            if(resultSource.getFeatures().length > 0){
                _this.mainMap.getView().fit(resultSource.getExtent(), {
                    size: _this.mainMap.getSize(),
                    duration:_this.duration
                });
            }

            if(bufferOptions != null && bufferOptions.hasOwnProperty('successCallBack')){
                bufferOptions.successCallBack(enterpriseList);
            }
        },
        error:function (error) {
            if(bufferOptions.hasOwnProperty('errorCallBack')){
                bufferOptions.errorCallBack(error);
            }
        }
    });
}

/**
 * 地表水快速溯源
 * @param riverCode 河流编号
 * @param stationId 地表水站点编号
 * @param controlLevels 控制级别
 * @param itemOptions 监测项目参数对象，可设置为null或对象，如是对象必须有如下属性
 *  itemCode：监测项目编号
 *  state：状态比较（gt：大于；lt：小于；ge：大于等于；le：小于等于）
 *  itemValue：监测项目值
 * @param callBackOptions，数据回调参数，具有如下属性：
 *  successCallBack:数据成功回调函数（可选）
 *  errorCallBack：数据失败回调函数（可选）
 *  clickCallBack:点击事件,形如function(property){...}
 */
C3GIS.prototype.findEnterpriseBySurfaceStation
    = function (riverCode,stationId,controlLevels,itemOptions,callBackOptions) {
    if(riverCode == null || riverCode == '') return;
    var _this = this,
        serverURL = _this.serverURL(),
        url = serverURL + 'api/datacenter/wastewater/enterpriselist?key=' + $.data(dataCache, 'key');
    url += "&river=" + riverCode;
    if(stationId != null && stationId != ''){
        url += "&station=" + stationId;
    }
    if(controlLevels != null && controlLevels != ''){
        url += "&controllevels=" + controlLevels;
    }
    if(itemOptions != null
        && itemOptions.hasOwnProperty('itemCode') && itemOptions['itemCode'] != null && itemOptions['itemCode'] != ''
        && itemOptions.hasOwnProperty('state') && itemOptions['state'] != null && itemOptions['state'] != ''
        && itemOptions.hasOwnProperty('itemValue') && itemOptions['itemValue'] != null && itemOptions['itemValue'] != ''){
        url += "&item=" + itemOptions['itemCode'];
        url += "&state=" + itemOptions['state'];
        url += "&value=" + itemOptions['itemValue'];
    }
    $.ajax({
        type: 'get',
        url:url,
        success: function(data) {
            if(data == null) return;
            var enterpriseList = JSON.parse(data),
                resultSource = new ol.source.Vector({
                    features: (new ol.format.GeoJSON()).readFeatures(enterpriseList)
                });
            //判断图层是否存在，如果图层已经存在则只重置数据源
            var resultLayer = _this.getLayByName('wasteWaterEnterprisrLayer');
            if(resultLayer != null){
                resultLayer.setSource(resultSource);
                if(resultSource.getFeatures().length > 1){
                    _this.mainMap.getView().fit(resultSource.getExtent(), {
                        size: _this.mainMap.getSize(),
                        duration:_this.duration
                    });
                }else if(resultSource.getFeatures().length == 1){
                    _this.mainMap.getView().animate({
                        center:resultSource.getFeatures()[0].getGeometry().getCoordinates(),
                        duration:_this.duration
                    });
                }

                if(callBackOptions != null && callBackOptions.hasOwnProperty('successCallBack')){
                    callBackOptions.successCallBack(enterpriseList);
                }
                return;
            }
            resultLayer = new ol.layer.Vector({
                source: resultSource,
                style:function (feature) {
                    var property = feature.getProperties();
                    return new ol.style.Style({
                        image: new ol.style.Icon(({
                            src:_this.getEnterpriseIconByType(property["industryCode"])
                        }))
                    })
                }
            });
            resultLayer.setProperties({'name':'wasteWaterEnterprisrLayer','layerType':'ol.layer.Vector'});
            _this.mainMap.addLayer(resultLayer);

            var pointerMove = {
                    pointerMoveStyle:function (feature) {
                        var property = feature.getProperties();
                        return new ol.style.Style({
                            image: new ol.style.Icon(({
                                src:_this.getEnterpriseIconByType(property["industryCode"])
                            })),
                            text:new ol.style.Text({
                                offsetY:-24,
                                font: '16px Microsoft YaHei Bold',    //字体与大小
                                backgroundFill: new ol.style.Fill({
                                    color: '#2b81ff'
                                }),
                                backgroundStroke: new ol.style.Stroke({
                                    color: '#2b81ff',
                                    width: 5
                                }),
                                fill: new ol.style.Fill({    //文字填充色
                                    color: '#fff'
                                }),
                                stroke: new ol.style.Stroke({    //文字边界宽度与颜色
                                    color: '#000',
                                    width: 3
                                }),

                                text:feature.get('enterpriseName')
                            })
                        });
                    }
                },
                click = {
                    clickCallBack:function(e) {
                        var arr=e.target;
                        var collection = arr.getFeatures();
                        var features = collection.getArray();
                        if(features.length > 0){
                            var stationAttr = features[0].getProperties();
                            if(callBackOptions != null && callBackOptions.hasOwnProperty('clickCallBack')){
                                callBackOptions.clickCallBack(stationAttr);
                            }
                        }
                    }
                };
            _this.addInteractionForVectorLayer('wasteWaterEnterprisrLayer',pointerMove,click);

            if(resultSource.getFeatures().length > 1){
                _this.mainMap.getView().fit(resultSource.getExtent(), {
                    size: _this.mainMap.getSize(),
                    duration:_this.duration
                });
            }else if(resultSource.getFeatures().length == 1){
                _this.mainMap.getView().animate({
                    center:resultSource.getFeatures()[0].getGeometry().getCoordinates(),
                    duration:_this.duration
                });
            }


            if(callBackOptions != null && callBackOptions.hasOwnProperty('successCallBack')){
                callBackOptions.successCallBack(enterpriseList);
            }
        },
        error:function (error) {
            if(callBackOptions != null && callBackOptions.hasOwnProperty('errorCallBack')){
                callBackOptions.errorCallBack(error);
            }
        }
    });
}

/**
 * 按站点编号高亮显示分段河流
 * @param stationId 站点编号
 */
C3GIS.prototype.highLightSeparatedRiver = function (stationId) {
    var _this = this, selectRiver,
        selectRivers = _this.filterFeatureFromVectorLayer('separatedriver',function (feature) {
            var result = false,property = feature.getProperties();
            if(property.hasOwnProperty('stationCode') && property['stationCode'] == stationId){
                result = true;
            }
            return result;
        });
    if(selectRivers.length > 0){
        var waterLevel,selectRiver = selectRivers[0],levelColor,lightColor='#FF0000';
        waterLevel = selectRiver.getProperties()['level'];
        switch(waterLevel){
            case "I":
                levelColor='#5cc15d';
                break;
            case "II":
                levelColor='#5cc15d';
                break;
            case "III":
                levelColor='#5cc15d';
                break;
            case "IV":
                levelColor='#FFED72';
                break;
            case "V":
                levelColor='#FF6A07';
                break;
            case "劣V":
                levelColor='#FF6A07';
                break;
            default:
                levelColor='#919096';
                break;
        }
        if(_this.hasOwnProperty('oTimer')){
            clearInterval(_this.oTimer);
        }
        //设置定时器以高亮显示
        _this.oTimer = setInterval(function () {
            var oldStyle = selectRiver.getStyle(),oldColor;
            if(oldStyle == null){
                //原始状态是给图层设置的style，单个feature是没style的，要先给选中的fea设置样式
                selectRiver.setStyle(new ol.style.Style({
                    stroke: new ol.style.Stroke({
                        color: lightColor
                    }),
                    fill: new ol.style.Fill({
                        color: lightColor
                    })
                }));
            }else {
                //交替给选中的feature设置style
                oldColor = oldStyle.getFill().getColor();
                if(oldColor == levelColor){
                    oldStyle.getFill().setColor(lightColor);
                    oldStyle.getStroke().setColor(lightColor);
                }else {
                    oldStyle.getFill().setColor(levelColor);
                    oldStyle.getStroke().setColor(levelColor);
                }
            }
            //设置style后要刷新Source
            _this.getLayByName('separatedriver').getSource().refresh();
        },400);
    }
}
/**
 * 取消分段河流的高亮显示
 */
C3GIS.prototype.removeHighLightRiver = function () {
    var _this = this;
    //删除定时器
    if(_this.hasOwnProperty('oTimer')){
        clearInterval(_this.oTimer);
        _this.oTimer = null;
    }
    //重置分段河流样式
    _this.getLayByName('separatedriver').setStyle(function(feature) {
        var property = feature.getProperties(),level,color;
        level = property.level;
        switch(level){
            case "I":
                color='#5cc15d';
                break;
            case "II":
                color='#5cc15d';
                break;
            case "III":
                color='#5cc15d';
                break;
            case "IV":
                color='#FFED72';
                break;
            case "V":
                color='#FF6A07';
                break;
            case "劣V":
                color='#FF6A07';
                break;
            default:
                color='#919096';
                break;
        }

        return new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: color
            }),
            fill: new ol.style.Fill({
                color: color
            })
        });
    });
}
/**
 * 根据空气AQI值获取大气点位监察面的颜色
 * @param aqiValue
 * @returns {*}
 */
C3GIS.prototype.getSurfaceColorByAQI = function (aqiValue) {
    var color;
    switch (true) {
        case aqiValue <= 50:
            color = "#3ae216";
            break;
        case aqiValue > 50 && aqiValue <= 60:
            color = "#feff92";
            break;
        case aqiValue > 60 && aqiValue <= 70:
            color = "#fffd64";
            break;
        case aqiValue > 70 && aqiValue <= 80:
            color = "#fcff20";
            break;
        case aqiValue > 80 && aqiValue <= 90:
            color = "#f0f222";
            break;
        case aqiValue > 90 && aqiValue <= 100:
            color = "#e1e400";
            break;
        case aqiValue > 100 && aqiValue <= 110:
            color = "#fdc266";
            break;
        case aqiValue > 110 && aqiValue <= 120:
            color = "#ffa964";
            break;
        case aqiValue > 120 && aqiValue <= 130:
            color = "#fb9645";
            break;
        case aqiValue > 130 && aqiValue <= 140:
            color = "#f27f22";
            break;
        case aqiValue > 140 && aqiValue <= 150:
            color = "#ed620e";
            break;
        case aqiValue > 150 && aqiValue <= 160:
            color = "#fa5b36";
            break;
        case aqiValue > 160 && aqiValue <= 170:
            color = "#fa4643";
            break;
        case aqiValue > 170 && aqiValue <= 180:
            color = "#f62b27";
            break;
        case aqiValue > 180 && aqiValue <= 190:
            color = "#f11414";
            break;
        case aqiValue > 190 && aqiValue <= 200:
            color = "#e21616";
            break;
        case aqiValue > 200 && aqiValue <= 220:
            color = "#fe5d7b";
            break;
        case aqiValue > 220 && aqiValue <= 240:
            color = "#ed5281";
            break;
        case aqiValue > 240 && aqiValue <= 260:
            color = "#e44273";
            break;
        case aqiValue > 260 && aqiValue <= 280:
            color = "#d73063";
            break;
        case aqiValue > 280 && aqiValue <= 300:
            color = "#c12152";
            break;
        case aqiValue > 300:
            color = "#9b0231";
            break;
        default:
            color = "#778899";
            break;
    }
    return color;
}

/**
 * 利用超图进行表面分析的通用方法
 * @param serviceUrl 分析服务地址
 * @param surfaceAnalystParams 分析服务参数对象,具有如下属性：
 *  surPoints：参与分析的点数据
 *  surZValues：参与分析的数据
 *  clipRegion：结果切割面（可选）
 *  hasZValue：是否将参与分析的点加入到结果集中（默认为false，可选）
 *  attrValues：其他属性信息（可选）
 * @param analystCallBack 分析服务回调函数，形如function(features){ ... }
 */
C3GIS.prototype.surfaceAnalysis_SuperMap = function (serviceUrl,surfaceAnalystParams,analystCallBack) {
    var _this = this,resultFeatures=[],resultFeature;

    if(serviceUrl == null || serviceUrl ==''
        || !surfaceAnalystParams.hasOwnProperty('surPoints')
        || surfaceAnalystParams.surPoints == null
        || surfaceAnalystParams.surPoints.length == 0
        || !surfaceAnalystParams.hasOwnProperty('surZValues')
        || surfaceAnalystParams.surZValues == null
        || surfaceAnalystParams.surZValues.length != surfaceAnalystParams.surPoints.length) {
        if(analystCallBack != null){
            analystCallBack(resultFeatures);
        }
    }

    // 将分析的点加入结果集
    if(surfaceAnalystParams.hasOwnProperty('hasZValue') && surfaceAnalystParams.hasZValue){
        for(var i = 0,len = surfaceAnalystParams.surPoints.length; i < len; i++){
            resultFeature = new ol.Feature({geometry: surPoints[i]});
            resultFeature.setProperties({'zvalue':surfaceAnalystParams.surZValues[i]});
            resultFeatures.push(resultFeature);
        }
    }


    //构造表面分析参数
    var surfaceAnalystParameters, surfaceAnalystService,
        extractParameter={
            datumValue: 0,
            interval: 5,
            resampleTolerance: 0.7,
            smoothMethod: SuperMap.SmoothMethod.BSPLINE,
            smoothness: 3
        };
    if(surfaceAnalystParams.hasOwnProperty('clipRegion') && surfaceAnalystParams.clipRegion != null){
        if(surfaceAnalystParams.clipRegion.getType() =='MultiPolygon'){
            extractParameter['clipRegion'] = surfaceAnalystParams.clipRegion.getPolygon(0);
        }else{
            extractParameter['clipRegion'] = surfaceAnalystParams.clipRegion;
        }
    }

    surfaceAnalystParameters = new SuperMap.GeometrySurfaceAnalystParameters({
        extractParameter: new SuperMap.SurfaceAnalystParametersSetting(extractParameter),
        points:surfaceAnalystParams.surPoints,
        zValues:surfaceAnalystParams.surZValues,
        resolution:0.004,
        surfaceAnalystMethod:SuperMap.SurfaceAnalystMethod.ISOREGION
    });
    // 表面分析
    surfaceAnalystService = new ol.supermap.SpatialAnalystService(serviceUrl);
    surfaceAnalystService.surfaceAnalysis(surfaceAnalystParameters,function (surfaceAnalystServiceResult) {
        var result = surfaceAnalystServiceResult.result,features;
        if (result && result.recordset && result.recordset.features) {
            features = (new ol.format.GeoJSON()).readFeatures(result.recordset.features);
            resultFeatures = resultFeatures.concat(features);
        }
        //表面分析结果回调
        if(analystCallBack != null){
            analystCallBack(resultFeatures,
                surfaceAnalystParams.hasOwnProperty('attrValues') ? surfaceAnalystParams.attrValues:null);
        }
    });
}

/**
 * 空气站点插值分析
 * @param airStationValues 参与空气插值的值，形如{'date':'...', 'value':[{'lat':..., 'lon':..., val:...}, ...], ...}
 * @param analysisCallBack 每次分析成功后的回调函数，用于地图以外的操作
 * @constructor
 */
C3GIS.prototype.AirStationSurfaceAnalysis = function (airStationValues,analysisCallBack) {
    var _this = this, serviceUrl,
        airSurfaceLayer = _this.getLayByName('airSurfaceLayer'),
        serverURL = _this.serverURL(),
        clipRegion = $.data(dataCache, 'region')[0].getGeometry(),
        sourceUrl = serverURL + 'api/ol/source/sourceurl?sourcename=superMapAnalysis&key=' + $.data(dataCache, 'key');
    if(airSurfaceLayer != null){
        airSurfaceLayer.getSource().clear();
    }
    if(airStationValues == null
        || !airStationValues.hasOwnProperty('value')
        || airStationValues.value == undefined
        || airStationValues.value == null
        || airStationValues.value.length == 0) {
        if(airStationValues.hasOwnProperty('date') && analysisCallBack != null){
            analysisCallBack(airStationValues.date);
        }
        return;
    }


    serviceUrl = $.data(dataCache, 'surfaceAnalysisUrl_SuperMap');

    if(serviceUrl == null || serviceUrl == undefined){
        $.ajax({
            type: 'get',
            url:sourceUrl,
            async: false,
            success:function (data) {
                if(data != null && data != ''){
                    serviceUrl = data;
                    $.data(dataCache, 'surfaceAnalysisUrl_SuperMap', data);
                }
            },
            error:function (error) {
                console.log(error);
            }
        })
    }

    if(serviceUrl != undefined && serviceUrl != ''){
        //分析完成的回调函数
        var analysisParma,surPoints,surZValues,dayValue,
            callBack = function (resultFeatures, attrValues) {
                var resultSource = new ol.source.Vector({
                    features: resultFeatures
                });

                if(airSurfaceLayer == null){
                    airSurfaceLayer = new ol.layer.Vector({
                        source: resultSource,
                        style:function (feature) {
                            var geometryType = feature.getGeometry().getType(),
                                property = feature.getProperties(),
                                color;
                            if (geometryType.toUpperCase() == "POINT"){
                                //空气站点样式
                                return new ol.style.Style({
                                    image: new ol.style.Icon(({
                                        src:_this.getAirIconByAQI(property.zvalue)
                                    }))
                                })
                            }else {
                                if(property.hasOwnProperty('dMinZValue')){
                                    color = _this.getSurfaceColorByAQI(property['dMinZValue']);
                                }else if(property.hasOwnProperty('DMINZVALUE')){
                                    color = _this.getSurfaceColorByAQI(property['DMINZVALUE']);
                                }

                                return new ol.style.Style({
                                    stroke: new ol.style.Stroke({
                                        color: color
                                    }),
                                    fill: new ol.style.Fill({
                                        color: color
                                    })
                                });
                            }
                        }
                    });
                    airSurfaceLayer.setProperties({'name':'airSurfaceLayer','layerType':'ol.layer.Vector'});
                    _this.mainMap.addLayer(airSurfaceLayer);
                }else {
                    airSurfaceLayer.setSource(resultSource);
                }

                if(analysisCallBack != null){
                    analysisCallBack(attrValues);
                }
            };

        dayValue = airStationValues['value'];
        if(dayValue != null && dayValue.length > 0){
            surPoints = [];
            surZValues = [];
            for(var j = 0,jLen = dayValue.length;j < jLen;j++){
                surPoints.push(new ol.geom.Point([parseFloat(dayValue[j]['lon']), parseFloat(dayValue[j]['lat'])]));
                surZValues.push(parseFloat(dayValue[j]['val']));
            }
            analysisParma = {
                'surPoints':surPoints,
                'surZValues':surZValues,
                'clipRegion':clipRegion,
                'attrValues':airStationValues['date']
            };
            _this.surfaceAnalysis_SuperMap(serviceUrl,analysisParma,callBack);
        }
    }
}

/**
 * 废气站点表面分析
 * @param stationValues 参与表面分析的值，形如{'date':'...', 'value':[{'lat':..., 'lon':..., val:...}, ...], ...}
 * @param analysisCallBack 每次分析成功后的回调函数，用于地图以外的操作
 */
C3GIS.prototype.psGasSurfaceAnalysis = function (stationValues,analysisCallBack) {
    var _this = this, serviceUrl,
        psSurfaceLayer = _this.getLayByName('psSurfaceLayer'),
        serverURL = _this.serverURL(),
        sourceUrl = serverURL + 'api/ol/source/sourceurl?sourcename=superMapAnalysis&key=' + $.data(dataCache, 'key');
    if(psSurfaceLayer != null){
        psSurfaceLayer.getSource().clear();
    }
    if(stationValues == null) return;


    serviceUrl = $.data(dataCache, 'surfaceAnalysisUrl_SuperMap');

    if(serviceUrl == null || serviceUrl == undefined){
        $.ajax({
            type: 'get',
            url:sourceUrl,
            async: false,
            success:function (data) {
                if(data != null && data != ''){
                    serviceUrl = data;
                    $.data(dataCache, 'surfaceAnalysisUrl_SuperMap', data);
                }
            },
            error:function (error) {
                console.log(error);
            }
        })
    }

    if(serviceUrl != undefined && serviceUrl != ''){
        //分析完成的回调函数
        var analysisParma,surPoints,surZValues,dayValue,
            callBack = function (resultFeatures, attrValues) {
                var resultSource = new ol.source.Vector({
                    features: resultFeatures
                });

                if(psSurfaceLayer == null){
                    psSurfaceLayer = new ol.layer.Vector({
                        source: resultSource,
                        style:function (feature) {
                            var property = feature.getProperties(),
                                color = this.getSurfaceColorByAQI(property['DMINZVALUE']);
                            return new ol.style.Style({
                                stroke: new ol.style.Stroke({
                                    color: color
                                }),
                                fill: new ol.style.Fill({
                                    color: color
                                })
                            });
                        }
                    });
                    psSurfaceLayer.setProperties({'name':'psSurfaceLayer','layerType':'ol.layer.Vector'});
                }else {
                    psSurfaceLayer.setSource(resultSource);
                }

                if(analysisCallBack != null){
                    analysisCallBack(attrValues);
                }
            };

        dayValue = stationValues['value'];
        if(dayValue != null && dayValue.length > 0){
            surPoints = [];
            surZValues = [];
            for(var j = 0,jLen = dayValue.length;j < jLen;j++){
                surPoints.push(new ol.geom.Point(parseFloat(dayValue[j]['lat']), parseFloat(dayValue[j]['lon'])));
                surZValues.push(dayValue[j]['val']);
            }
            analysisParma = {
                'surPoints':surPoints,
                'surZValues':surZValues,
                'attrValues':stationValues['date']
            };
            _this.surfaceAnalysis_SuperMap(serviceUrl,analysisParma,callBack);
        }
    }
}
/**
 * 地图上生成echarts统计图表
 * @param chartOptions 图标参数数组，每个元素具有如下属性：
 *  reginCode 行政区编号
 *  chartOption 每个行政区对应的统计图标参数
 */
C3GIS.prototype.createRegionChart = function (chartOptions) {
    var _this = this,childregions = $.data(dataCache, 'childregions'),reginCode;
    if(chartOptions == null || chartOptions.length == 0 || childregions == undefined || childregions == null) return;
    _this.addLayerFromFeatures('regionLayer',childregions,function (feature) {
        return new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: 'blue',
                lineDash: [4],
                width: 1
            }),
            fill: new ol.style.Fill({
                color: 'rgba(0, 0, 255, 0)'
            })
        })
    });
    for(var i = 0,len = childregions.length;i < len;i++){
        reginCode = childregions[i].getProperties()['reginCode'];
        for(var index = 0,indexLen = chartOptions.length;index < indexLen;index++){
            if(chartOptions[index]['reginCode'] == reginCode){
                chartOptions[index]['reginPoint'] = ol.extent.getCenter(childregions[i].getGeometry().getExtent());
                break;
            }
        }
    }
    _this.createChartOverlay(chartOptions);
    _this.zoomMapByVectorLayer('regionLayer',null);
}
/**********************************bussiness enddd*****************************************/